package com.atguigu.myjuc.rwlock;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 *
 *
 *  * 写线程首先获取写锁，更新数据，然后将锁降级为读锁。读线程在获取读锁后读取数据。
 *  * 这个过程演示了锁降级的概念，允许多个线程在持有读锁的情况下同时访问数据，
 *  * 提高了并发性能。`
 *  * 请注意，在锁降级期间，我们要确保数据的一致性，即在降级为读锁之前和之后都可以正确读取数据。
 *  * 这是锁降级的关键部分。（先获取读锁，再释放写锁）`
 *
 */

public class LockDowngradingDemo {
    private  final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    private  final Lock readLock = readWriteLock.readLock();
    private  final Lock writeLock = readWriteLock.writeLock();
    private int date = 0;

    public int readDate(){
        readLock.lock();
        try {
            return date;
        }finally {
            readLock.unlock();
        }
    }

    public void writeLock(int newdate){
        writeLock.lock();//获取读锁
        try {
            date = newdate; //更新新数据
            System.out.println("新数据："+newdate);
            readLock.lock();//降级为读锁 在释放写锁之前获取读锁
        }finally {
            writeLock.unlock();//释放读锁
        }
        try {
            //在持有读锁的情况下进行下一步操作 读自己已写
            newdate = date;
            System.out.println("读取当前数据"+date);
        }finally {
            readLock.unlock();//释放读锁
        }

    }


    public static void main(String[] args) {
        LockDowngradingDemo lockDowngradingDemo = new LockDowngradingDemo();
        new Thread(()->{
            lockDowngradingDemo.writeLock(0);
        }).start();

        new Thread(()->{
            System.out.println("当前值为："+lockDowngradingDemo.readDate());


        }).start();
    }


}
